package com.fengwk.user.service.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.fengwk.resource.face.client.FileClient;
import com.fengwk.resource.face.model.File;
import com.fengwk.support.code.Sequence;
import com.fengwk.support.exception.BaseException;
import com.fengwk.support.page.PageInfo;
import com.fengwk.support.util.CollectionUtils;
import com.fengwk.support.util.StringUtils;
import com.fengwk.user.dao.UsUserDao;
import com.fengwk.user.dao.UsUserRoleLinkDao;
import com.fengwk.user.face.entity.UsUser;
import com.fengwk.user.face.entity.UsUserRoleLink;
import com.fengwk.user.face.model.User;
import com.fengwk.user.service.UserService;

@Service
public class UserServiceImpl implements UserService {

	@Autowired
	private FileClient fileClient;
	
	@Autowired
	private UsUserDao usUserDao;
	@Autowired
	private UsUserRoleLinkDao usUserRoleLinkDao;
	
	@Transactional
	@Override
	public User saveUser(Long avatarId, String username, String email, String mobilePhone, String password,
	        String nickname, String realName, String idCard, Integer sex, Long birthTime) {
		long currentTime = System.currentTimeMillis();
		UsUser usUser = new UsUser();
		usUser.setUserId(Sequence.next());
		usUser.setAvatarId(avatarId);
		usUser.setUsername(username);
		usUser.setEmail(email);
		usUser.setMobilePhone(mobilePhone);
		usUser.setPassword(password);
		usUser.setNickname(nickname);
		usUser.setRealName(realName);
		usUser.setIdCard(idCard);
		usUser.setSex(sex);
		usUser.setBirthTime(birthTime);
		usUser.setCreateTime(currentTime);
		usUser.setUpdateTime(currentTime);
		usUser.setStatus(UsUser.STATUS_DEFAULT);
		usUserDao.insert(usUser);
		return toUser(usUser);
	}

	@Transactional
	@Override
	public User removeUser(Long userId) {
		return updateUser(userId, null, null, null, null, null, null, null, null, null, null, UsUser.STATUS_DELETE);
	}

	@Transactional
	@Override
	public User updateUser(Long userId, Long avatarId, String username, String email, String mobilePhone,
			String password, String nickname, String realName, String idCard, Integer sex, Long birthTime, Integer status) {
		UsUser usUser = usUserDao.findByUserId(userId);
		if (usUser == null) 
			throw new BaseException("用户[userId:" + userId + "]不存在");
		if (usUser != null) {
			if (avatarId != null)
				usUser.setAvatarId(avatarId);
			if (username != null)
				usUser.setUsername(username);
			if (email != null)
				usUser.setEmail(email);
			if (mobilePhone != null)
				usUser.setMobilePhone(mobilePhone);
			if (password != null)
				usUser.setPassword(password);
			if (nickname != null)
			    usUser.setNickname(nickname);
			if (realName != null)
			    usUser.setRealName(realName);
			if (idCard != null)
				usUser.setIdCard(idCard);
			if (sex != null)
				usUser.setSex(sex);
			if (birthTime != null)
				usUser.setBirthTime(birthTime);
			if (status != null)
				usUser.setStatus(status);
			usUser.setUpdateTime(System.currentTimeMillis());
			usUserDao.updateByUserId(usUser);
		}
		return toUser(usUser);
	}
	
	@Transactional
	@Override
	public void synRole(Long userId, Collection<Long> roleIds) {
		usUserRoleLinkDao.deleteByUserId(userId);
		addRole(userId, roleIds);
	}

	@Transactional
	@Override
	public void addRole(Long userId, Collection<Long> roleIds) {
		List<UsUserRoleLink> usUserRoleLinkList = CollectionUtils.toListWithTypeConvert(
				roleIds, roleId -> {
					UsUserRoleLink usUserRoleLink = new UsUserRoleLink();
					usUserRoleLink.setRecordId(Sequence.next());
					usUserRoleLink.setUserId(userId);
					usUserRoleLink.setRoleId(roleId);
					return usUserRoleLink;
				});
		if (CollectionUtils.isNotBlank(usUserRoleLinkList)) {
			usUserRoleLinkDao.batchInsert(usUserRoleLinkList);
		}
	}

	@Transactional
	@Override
	public void removeRole(Long userId, Collection<Long> roleIds) {
		usUserRoleLinkDao.deleteByUserIdAndRoleIds(userId, roleIds);
	}
	
	@Override
	public User getUserByUsername(String username) {
		if (StringUtils.isBlank(username)) {
			return null;
		}
		return toUser(usUserDao.findByUsername(username));
	}

	@Override
	public User getUserByMobilePhone(String mobilePhone) {
		if (StringUtils.isBlank(mobilePhone)) {
			return null;
		}
		return toUser(usUserDao.findByMobilePhone(mobilePhone));
	}

	@Override
	public User getUserByEmail(String email) {
		if (StringUtils.isBlank(email)) {
			return null;
		}
		return toUser(usUserDao.findByEmail(email));
	}
	
	@Override
	public User getUserByUserId(Long userId) {
		if (userId == null) {
			return null;
		}
		return toUser(usUserDao.findByUserId(userId));
	}

	@Override
	public List<User> listUserByUserIds(Collection<Long> userIds) {
		return toUserList(usUserDao.queryInUserIds(userIds));
	}
	
	@Override
	public PageInfo<User> pageUser(int pageNum, int pageSize) {
		PageInfo<User> pageInfo = new PageInfo<>(pageNum, pageSize);
		List<UsUser> usUserList = usUserDao.page(pageInfo.queryStartRow(), pageInfo.queryPageSize());
		pageInfo.setTotal(usUserDao.countAll());
		pageInfo.setList(toUserList(usUserList));
		return pageInfo;
	}
	
	private User toUser(UsUser usUser) {
		return CollectionUtils.getFirstFromList(toUserList(CollectionUtils.buildList(usUser, true)));
	}
	
	private List<User> toUserList(Collection<UsUser> usUsers) {
		List<File> avatarList = new ArrayList<>();
		List<Long> avatarIdList = CollectionUtils.toListWithTypeConvert(
				usUsers, usUser -> usUser.getAvatarId());
		if (CollectionUtils.isNotBlank(avatarIdList)) {
			avatarList = fileClient.listByFileIds(avatarIdList);
		}
		Map<Long, File> avatarIdAvatarMap = CollectionUtils.toMap(avatarList, avatar -> avatar.getFileId());
		
		
		return CollectionUtils.toListWithTypeConvert(
				usUsers, usUser -> {
					Long avatarId = usUser.getAvatarId();
					File avatar = null;
					if (avatarId != null)
						avatar = avatarIdAvatarMap.get(avatarId);
					User user = new User();
					user.setUserId(usUser.getUserId());
					user.setAvatar(avatar);
					user.setUsername(usUser.getUsername());
					user.setEmail(usUser.getEmail());
					user.setMobilePhone(usUser.getMobilePhone());
					user.setPassword(usUser.getPassword());
					user.setNickname(usUser.getNickname());
					user.setRealName(usUser.getRealName());
					user.setIdCard(usUser.getIdCard());
					user.setSex(usUser.getSex());
					user.setBirthTime(usUser.getBirthTime());
					user.setCreateTime(usUser.getCreateTime());
					user.setUpdateTime(usUser.getUpdateTime());
					user.setStatus(usUser.getStatus());
					return user;
				});
	}
	
}
